home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Shareware Grab Bag
/
Shareware Grab Bag.iso
/
090
/
cmln1084.arc
/
PORTC3.LTG
< prev
next >
Wrap
Text File
|
1986-10-01
|
6KB
|
294 lines
/* - dgsx.c
Utilites to create and search reserved word tables. In-core digital
search trees created by the 'dgsm.c' routines are compressed and all
inter-node references are converted to indexes rather than absolute
memory references.
*/
#include <stdio.h>
#include "dgsdefs.h"
#include "algnm.h"
static struct tblctrl *ctrl;
static struct xtbctrl *xtrl;
static char *base;
static ALIGN u;
#ifndef EXACT
static int glsym;
#endif
/*- CDGX.C ---------------------------------------------------------
Translate an in-core tree into a compressed, index-based tree, with
no 'successor' indexes. 'cdgx' allocates twice the actual size of
the in-core tree to allow for allignment bytes.
------------------------------------------------------------------*/
cdgx(gctrl,gxctrl)
struct tblctrl *gctrl;
struct xtbctrl *gxctrl;
{
char *malloc();
ctrl=gctrl;
gxctrl->nentry=gctrl->nentry;
gxctrl->depth=gctrl->depth;
gxctrl->tblptr=base=u.cptr=malloc((unsigned)(2*mtrsiz(gctrl)));
if(base==NULL)
return(FALSE);
dgx(ctrl->syptr,0);
gxctrl->size=(u.cptr-base);
return(TRUE);
}
/* Create a compressed node.
'u' always points to the next free location. */
dgx(mptr,lvl)
struct synode *mptr;
int lvl;
{
char *flgptr,*strcpy();
struct llist *lptr;
unsigned short int *laltptr;
if(mptr != NULL)
{
if(lvl < ctrl->depth)
{
/* create the flag, store the node char. */
flgptr=u.cptr++;
*flgptr=NULL;
*u.cptr++=mptr->sym;
/* store the aligned symbol # */
if(mptr->symno)
{
*flgptr |= SYM;
*uslgn(u)=mptr->symno;
u.usptr++;
}
/* make room for the 'alternate' index if necessary */
if(mptr->alt)
{
*flgptr |= ALT;
laltptr=uslgn(u);
u.usptr++;
}
if(dgx(mptr->suc,lvl+1))
*flgptr |= SUC;
if(*flgptr & ALT)
{
*laltptr=dgx(mptr->alt,lvl);
}
return(flgptr-base);
}
/* proceed into the linked list */
else
{
for(lptr=(struct llist *)mptr; lptr != NULL; lptr=lptr->suc)
{
strcpy(u.cptr,lptr->symptr);
u.cptr+=(strlen(lptr->symptr)+1);
*uslgn(u)=lptr->symno;
u.usptr++;
}
*u.cptr++=NULL;
return(TRUE);
}
}
else return(NULL);
}
/*- SGX.C ------------------------------------------------------------
Search a compressed digital search tree. Returned value depends on
the definition of 'EXACT'.
EXACT = TRUE; return the symbol number if an exact match
is found, or NULL if not.
EXACT = FALSE; return : a) the symbol number if an exact match is
found.
b) the negative of the symbol number if
an inexact match is found.
c) NULL if no match is found.
---------------------------------------------------------------------*/
sgx(gxtrl,c)
struct xtbctrl *gxtrl;
char *c;
{
#ifndef EXACT
int n;
#endif
xtrl=gxtrl;
base=xtrl->tblptr;
#ifndef EXACT
glsym=NULL;
return((n=sx(xtrl->tblptr,c,0)) ? n : -glsym);
#endif
#ifdef EXACT
return(sx(xtrl->tblptr,c,0));
#endif
}
/* Search a compressed node */
sx(flg,c,lvl)
char *flg,*c;
int lvl;
{
char *altptr(),*sucptr(),*ptr;
int t;
if(flg)
{
if(lvl < xtrl->depth)
{
if(*c < *(flg+1))
return(NULL);
else if(*c > *(flg+1))
return(sx(altptr(flg),c,lvl));
else
{
#ifndef EXACT
glsym=symn(flg);
#endif
return(*++c != '\0' ? sx(sucptr(flg),c,lvl+1) : symn(flg));
}
}
/* search the linked list */
else
{
for(u.cptr=flg; *u.cptr != NULL; )
{
ptr=u.cptr;
u.cptr+=strlen(u.cptr)+1;
uslgn(u);
#ifndef EXACT
if(fndsub(ptr,c) == 0)
glsym=*u.usptr;
#endif
if((t=strcmp(c,ptr)) == 0)
return((int) *u.usptr);
else if(t < 0)
return(NULL);
u.usptr++;
}
return(NULL);
}
}
else return(NULL);
}
/* routines to extract values/pointers from a compressed node */
symn(flg)
char *flg;
{
if(*flg & SYM)
{
u.cptr=flg+2;
return((int)*uslgn(u));
}
else return(NULL);
}
char *altptr(flg)
char *flg;
{
if(*flg & ALT)
{
u.cptr=flg+2;
uslgn(u);
if(*flg & SYM)
u.usptr++;
return(base+*u.usptr);
}
else return(NULL);
}
char *sucptr(flg)
char *flg;
{
if(*flg & SUC)
{
u.cptr=flg+2;
if(*flg & SYM)
{
uslgn(u);
u.usptr++;
}
if(*flg & ALT)
{
uslgn(u);
u.usptr++;
}
return(u.cptr);
}
else return(NULL);
}
/*- XPRT ---------------------------------------------------
Dump a compressed digital search tree.
-----------------------------------------------------------*/
xprt(gxctrl)
struct xtbctrl *gxctrl;
{
xtrl=gxctrl;
base=xtrl->tblptr;
xp(xtrl->tblptr,0);
}
/* print out the nodes */
xp(flg,lvl)
int lvl;
char *flg;
{
char *sucptr(),*altptr();
if(flg)
{
if(lvl < xtrl->depth)
{
u.cptr=flg;
fprintf(stdout,"%d flag: %d char: %c",(flg-base),*flg,*(flg+1));
fprintf(stdout," symbol #: %d ",symn(flg));
fprintf(stdout,"suc: %d ",(sucptr(flg) ? sucptr(flg)-base : NULL));
fprintf(stdout," alt: %d\n",(altptr(flg) ? altptr(flg)-base : NULL));
xp(sucptr(flg),lvl+1);
xp(altptr(flg),lvl);
}
else
{
for(u.cptr=flg; *u.cptr !=NULL; )
{
fprintf(stdout," %s ",u.cptr);
u.cptr+=strlen(u.cptr)+1;
uslgn(u);
fprintf(stdout,"%d\n",*u.usptr++);
}
}
}
}
/*--- FNDSUB ----------------------------------------------------------
Return the index (i) of a substring within a string (stg[i]), or EOF
on no match. Both strings must be null-terminated.
----------------------------------------------------------------------*/
fndsub(sub,stg)
char *sub,*stg;
{
char *ptr1,*ptr2,*base=stg;
for(;;stg++)
{
for(ptr1=sub, ptr2=stg; *ptr1==*ptr2 && *ptr1!='\0'; ptr1++, ptr2++)
;
if(*ptr1=='\0')
return((int)(stg-base));
else if(*ptr2=='\0')
return(EOF);
}
}